package com.boot.learning.captcha;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.StringRedisTemplate;

import lombok.Getter;
import lombok.Setter;

/**
 * 验证码业务实现逻辑
 * 
 * @version 1.0
 * @author fuhw
 */
public class RedisCaptchaService implements CaptchaService {

	private final static String DEFAULT_CAPTCHA_PREFIX = "mcar.captcha.";

	private final static long DEFAULT_EXPIRY = 1000 * 60 * 10; // 10 min

	private static Logger logger = LoggerFactory.getLogger( RedisCaptchaService.class );

	private RedisOperations<String, String> redisOperations;

	@Setter
	@Getter
	private CaptchaGenerator captchaGenerator = new NumberCaptchaGenerator();

	@Setter
	@Getter
	private long expiry = DEFAULT_EXPIRY;

	private String prefix = DEFAULT_CAPTCHA_PREFIX;

	public void setPrefix( String prefix ){
		if (!prefix.endsWith( "." )) {
			prefix += ".";
		}
		this.prefix = prefix;
	}

	public RedisCaptchaService( RedisConnectionFactory connectionFactory ) {
		super();
		this.redisOperations = new StringRedisTemplate( connectionFactory );
	}

	@Override
	public Captcha create( String mobile ){
		String code = captchaGenerator.gener();
		String key = keyForMobile( mobile );
		
		redisOperations.opsForValue().set( key, code );
		redisOperations.expire( key, expiry, TimeUnit.MILLISECONDS );
		
		Date expires = new Date( System.currentTimeMillis() + expiry );
		return new Captcha( code, mobile, expires );
	}

	@Override
	public String get( String mobile ){
		String key = keyForMobile( mobile );
		return redisOperations.opsForValue().get( key );
	}

	@Override
	public void delete( String mobile ){
		logger.info( "delete a captcha from captchaStore!" );
		String key = keyForMobile( mobile );
		redisOperations.delete( key );
	}

	private String keyForMobile( String mobile ){
		return prefix + mobile;
	}
}
